# Create your views here.
from django_celery_beat.models import PeriodicTask
from rest_framework.decorators import action

from apitest import serializers
from apitest.models import ProjectInfo, ModuleInfo, TestApiInfo, EnvInfo, TestCase, TestApiResult
from apitest.serializers import ProjectInfoSerializer, ModuleInfoSerializer, TestApiInfoSerializer, EnvInfoSerializer, \
    TestCaseSerializer, TestApiResultSerializer, ExportTestApiInfoSerializer, TestApiInfoImportSerializer
from apitest.utils.RequestUtil import RequestUtil
from dvadmin.utils.json_response import ErrorResponse, DetailResponse, SuccessResponse
from dvadmin.utils.serializers import CustomModelSerializer
from dvadmin.utils.viewset import CustomModelViewSet


class EnvInfoViewSet(CustomModelViewSet):
    """
    list:查询
    create:新增
    update:修改
    retrieve:单例
    destroy:删除
    """
    queryset = EnvInfo.objects.all()
    serializer_class = EnvInfoSerializer


class ProjectViewSet(CustomModelViewSet):
    """
    list:查询
    create:新增
    update:修改
    retrieve:单例
    destroy:删除
    """
    queryset = ProjectInfo.objects.all()
    serializer_class = ProjectInfoSerializer
    filter_fields = ['project_name', 'responsible_name']  # 精准搜索


class ModuleInfoViewSet(CustomModelViewSet):
    """
    list:查询
    create:新增
    update:修改
    retrieve:单例
    destroy:删除
    """
    queryset = ModuleInfo.objects.all()
    serializer_class = ModuleInfoSerializer
    # filter_fields = ['module_name', 'stauts'] #精准搜索





class TestApiInfoViewSet(CustomModelViewSet):
    """
    list:查询
    create:新增
    update:修改
    retrieve:单例
    destroy:删除
    """
    queryset = TestApiInfo.objects.all()
    serializer_class = TestApiInfoSerializer
    search_fields = ["name"]

    export_field_label = {
        "name": "测试用例",
        "url": "请求地址",
        "method_name": "协议类型",
        'project_name':"所属项目",
        'module_name': "所属模块",
        'create_datetime':"创建时间"
    }
    export_serializer_class = ExportTestApiInfoSerializer


    import_serializer_class = TestApiInfoImportSerializer
    import_field_dict = {
        "name": "测试用例",
        "url": "请求地址",
        "method": {
            "title": "协议类型",
            "choices": {
                "data": {"GET": 0, "POST": 1, "PUT": 2,'DELETED':3},
            }
        },
        "headers": "头部信息(json)",
        # "params_type": {
        #     "title": "参数类型",
        #     "choices": {
        #         "data": {"parmas": 1, "json": 2},
        #     }
        # },
        "params": "params类型字段(kv)",
        "jsonbody": "json类型字段(json)",
        "verification": "检查点",
        'extract':'关联字段',
        "project_belong": {"title": "工程信息", "choices": {"queryset": ProjectInfo.objects.all(), "values_name": "project_name"}},
        "module_belong": {"title": "模块信息", "choices": {"queryset": ModuleInfo.objects.all(), "values_name": "module_name"}},
    }

    @action(methods=["PUT"], detail=True)
    def apiTest(self, request, pk):
        """
        密码重置
        """
        apiinfo = TestApiInfo.objects.filter(id=pk).first()
        if apiinfo:
            api = RequestUtil()
            if apiinfo.params_type == 1:
                data = apiinfo.params
                data_parmas = {}
                if not data:
                    for item in data.split("&"):
                        kvs = item.split("=")
                        key = kvs[0]
                        value = kvs[1]
                        data_parmas[key] = value

                api.send_request(apiinfo.get_method_display(), apiinfo.url,
                                 verification=apiinfo.verification, case_desc=apiinfo.description,
                                 extract=apiinfo.extract, headers=apiinfo.headers, data=data_parmas)
            else:
                api.send_request(apiinfo.get_method_display(), apiinfo.url,
                                 verification=apiinfo.verification, case_desc=apiinfo.description,
                                 extract=apiinfo.extract, headers=apiinfo.headers, json=apiinfo.jsonbody)
            print(api.get_result())
            result_dic = api.get_result()
            resultModel = TestApiResult()
            resultModel.project_belong = apiinfo.project_belong
            resultModel.module_belong = apiinfo.module_belong
            resultModel.api_belong = apiinfo
            resultModel.took_time = result_dic['took_time']
            resultModel.result = result_dic['response'][:100]
            resultModel.verification = result_dic['check_result']
            resultModel.save()
            return DetailResponse(data=None, msg="测试成功")
        else:
            return ErrorResponse(msg="测试用例不存在")


class TestCaseViewSet(CustomModelViewSet):
    """
    list:查询
    create:新增
    update:修改
    retrieve:单例
    destroy:删除
    """
    queryset = TestCase.objects.all()
    serializer_class = TestCaseSerializer

    @action(methods=["PUT","POST"], detail=True)
    def caseTest(self, request, pk):
        testcase = TestCase.objects.get(id=pk)
        if testcase:
            apis = testcase.apis.all() #many to many
            print(apis)
            api = RequestUtil()
            for apiinfo in apis:
                if apiinfo.params_type == 1:
                    data = apiinfo.params
                    data_parmas = {}
                    if not data:
                        for item in data.split("&"):
                            kvs = item.split("=")
                            key = kvs[0]
                            value = kvs[1]
                            data_parmas[key] = value

                    api.send_request(apiinfo.get_method_display(), apiinfo.url,
                                     verification=apiinfo.verification, case_desc=apiinfo.description,
                                     extract=apiinfo.extract, headers=apiinfo.headers, data=data_parmas)
                else:
                    api.send_request(apiinfo.get_method_display(), apiinfo.url,
                                     verification=apiinfo.verification, case_desc=apiinfo.description,
                                     extract=apiinfo.extract, headers=apiinfo.headers, json=apiinfo.jsonbody)
                print(api.get_result())
                result_dic = api.get_result()
                resultModel = TestApiResult()
                resultModel.project_belong = apiinfo.project_belong
                resultModel.module_belong = apiinfo.module_belong
                resultModel.api_belong = apiinfo
                resultModel.case_belong = testcase
                resultModel.took_time = result_dic['took_time']
                resultModel.result = result_dic['response'][:100]
                resultModel.verification = result_dic['check_result']
                resultModel.save()

            return DetailResponse(data=None, msg="测试成功")
        else:
            return ErrorResponse(msg="测试用例不存在")

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        if instance.task_id is not None:
           try:
               task = PeriodicTask.objects.get(id=instance.task_id)
               task.delete()
           except:
               print("task不存")
        self.perform_destroy(instance)
        return SuccessResponse(data=[], msg="删除成功")





class TestApiResultViewSet(CustomModelViewSet):
    """
    list:查询
    create:新增
    update:修改
    retrieve:单例
    destroy:删除
    """
    queryset = TestApiResult.objects.all()
    serializer_class = TestApiResultSerializer

    @action(methods=["GET"], detail=False)
    def count(self, request):
        body_data = request.data.copy()
        print(body_data)
        # 饼图统计
        allresult = TestApiResult.objects.all().values()
        success_result = list(filter(lambda elem: elem["verification"] == '检查成功', allresult));
        fail_result = list(filter(lambda elem: elem["verification"] == '检查失败', allresult));
        skip_result = list(filter(lambda elem: elem["verification"] == '没有设置检查点', allresult));
        pie = []
        pie.append({'name': '检查成功', "value": len(success_result)})
        pie.append({'name': '检查失败', "value": len(fail_result)})
        pie.append({'name': '跳过检查', "value": len(skip_result)})
        result_data = {}
        result_data['apicount'] = pie
        # 完成率
        api_testd_count = len(TestApiResult.objects.all().values('api_belong').distinct())
        all_api_count = len(TestApiInfo.objects.all())
        result_data['finshed'] = round((api_testd_count * 100) / all_api_count)
        # 其他统计参数
        result_data["allApis"] = all_api_count
        result_data["testApis"] = api_testd_count
        result_data["total"] = len(allresult)
        result_data["success"] = len(success_result)
        result_data["fail"] = len(fail_result)
        result_data["skip"] = len(skip_result)
        return DetailResponse(data=result_data, msg="测试成功")